//
// Created by 86155 on 2025/4/15.
//
#include "llvm/MC/TargetRegistry.h"
#include "TargetInfo/FeTargetInfo.h"
#include "FeMCAsmInfo.h"
#include "FeInstrInfo.h"
#include "FeRegisterInfo.h"
#include "FeSubtarget.h"
#include "FeMCTargetDesc.h"
#include "FeInstPrinter.h"

#include "llvm/MC/MCInstrInfo.h"
#include "llvm/MC/MCRegisterInfo.h"
#include "llvm/MC/MCSubtargetInfo.h"
#include "llvm/MC/TargetRegistry.h"

using namespace llvm;
#define GET_INSTRINFO_MC_DESC
#include "FeGenInstrInfo.inc"

#define GET_REGINFO_MC_DESC
#include "FeGenRegisterInfo.inc"

#define GET_SUBTARGETINFO_MC_DESC
#include "FeGenSubtargetInfo.inc"

namespace {
//汇编信息
MCAsmInfo *createFeMCAsmInfo(const MCRegisterInfo &MRI, const Triple &TT,
                              const MCTargetOptions &Options) {
  return new FeMCAsmInfo(TT);
}
//指令信息
MCInstrInfo *createFeMCInstrInfo() {
  MCInstrInfo *X = new MCInstrInfo();
  InitFeMCInstrInfo(X);
  return X;
}

MCInstPrinter *createFeMCInstPrinter(const Triple &T, unsigned SyntaxVariant,
                                      const MCAsmInfo &MAI,
                                      const MCInstrInfo &MII,
                                      const MCRegisterInfo &MRI) {
  return new FeInstPrinter(MAI, MII, MRI);
}
//寄存器信息
MCRegisterInfo *createFeMCRegisterInfo(const Triple &TT) {
  MCRegisterInfo *X = new MCRegisterInfo();
  InitFeMCRegisterInfo(X, Fe::RA);
  return X;
}

MCSubtargetInfo *createFeMCSubtargetInfo(const Triple &TT, StringRef CPU,
                                          StringRef FS) {
  if (CPU.empty()) {
    CPU = "fe";
  }
  return createFeMCSubtargetInfoImpl(TT, CPU, CPU, FS); //tablegen生成
}
}
/*
 * llc的目标后端都必须实现各自的void LLVMInitializeXXXTargetMC()函数。否则，编译目标后端MyRISCV时会报错undefined reference to 'LLVMInitializeFeTargetMC'。
 * */
//注册信息 和添加target类似 固定操作
extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeFeTargetMC() {
  TargetRegistry::RegisterMCAsmInfo(getFeTarget(), createFeMCAsmInfo);
  TargetRegistry::RegisterMCInstrInfo(getFeTarget(), createFeMCInstrInfo);
  TargetRegistry::RegisterMCRegInfo(getFeTarget(), createFeMCRegisterInfo);
  TargetRegistry::RegisterMCSubtargetInfo(getFeTarget(), createFeMCSubtargetInfo);
  TargetRegistry::RegisterMCInstPrinter(getFeTarget(), createFeMCInstPrinter);
}